<?php
/**
 ***********************************************************************************************************************
 * 音频分析工具
 * wav音频格式基础知识:http://www.cnblogs.com/lidabo/p/3729615.html
 * http://ffmpeg-php.sourceforge.net/
 * https://github.com/PHP-FFMpeg/PHP-FFMpeg
 * http://apiv2.online-convert.com/
 * <?php exec(ffmpeg -i audio.amr testwav.wav) ?>
 * ffmpeg -i audio.amr -ar 22050 -ab 32 -map_meta_data audio.wav:audio.amr audio.wav
 *  author: ysp
 ***********************************************************************************************************************
 */
namespace util\audio;

use core\action;
use model\file\file;

class AudioUtil
{
    /**检测音频文件是否是8k16位
     * 注意:路径中不要带中文
     */
    public static function checkWav8K16Bit($audioPath)
    {
        if(!is_string($audioPath)||!$audioPath||!file_exists($audioPath)){
            return false;
        }
        //$audioPath=iconv('UTF-8','GB2312//IGNORE',$audioPath);//防止路径中带中文
        //先检测是否是wav格式文件
        $audioFormat=self::checkFileIsWav($audioPath);
        if(!$audioFormat||'audio/wav'!=$audioFormat||'audio/x-wav'!=$audioFormat){
            return false;
        }
        $fp = $d = $data = $formats = $bit = $chn = '0';
        $fp = fopen($audioPath, 'r');
        //前面20位可忽略
        fseek($fp, 20);
        //接下来18位是wav音频文件头信息
        $d = fread($fp, 18);
        //finfo_open();
        //将二进制字符串按照wav头信息解码
        $data = unpack('vfmtType/vchannel/VsampleRate/VbytesPerSec/valignment/vbits/vext', $d);
        //echo json_encode($data);exit;
        if(8000 !=$data['sampleRate'] || 16 !=$data['bits']){
            //非8k16位
            return false;
        }
//        $formats = [0x0001 => 'PCM', 0x0003 => 'IEEE Float', 0x0006 => 'A-LAW', 0x0007 => 'MuLAW', 0xFFFE => 'Extensible',];
//        $format=$formats[$data['fmtType']];
//        $bit = rtrim($data['sampleRate'], "0") * rtrim($data['bytesPerSec'], "0");
//        //$chn = ($data['channel'] = 1) ? "Mono" : "Stereo";
//        $chn = ($data['channel'] = 1) ? "单声道" : "双声道(立体声)";
//        fclose($fp);
//        echo "格式:{$format} 采样频率:{$data['sampleRate']}Hz 位:{$data['bits']}bit 声道:{$chn} <br/>";
//        if (!($formats[$data['fmtType']]=="A-LAW" && $data['channel']==1 && $data['bytesPerSec']<=8000 && $bit<=64) &&
//            !($formats[$data['fmtType']]=="PCM" && $data['channel']==1 && $data['bytesPerSec']<=16000 && $bit<=512)) {
//            echo "wrong format";
//        }
        return true;

    }

    /**
     * 检测是否是音频文件
     */
    public static function checkFileIsAudio( $audioPath )
    {
        if(!is_string($audioPath)||!$audioPath||!file_exists($audioPath)){
            return false;
        }
        $allowed = [
            'audio/mpeg', 'audio/x-mpeg', 'audio/mpeg3', 'audio/x-mpeg-3', 'audio/aiff',
            'audio/mid', 'audio/x-aiff', 'audio/x-mpequrl','audio/midi', 'audio/x-mid',
            'audio/x-midi','audio/wav','audio/x-wav','audio/xm','audio/x-aac','audio/basic',
            'audio/flac','audio/mp4','audio/x-matroska','audio/ogg','audio/s3m','audio/x-ms-wax',
            'audio/xm'//video/mp4
        ];
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $type = finfo_file($finfo, $audioPath );
        //echo '文件格式:'.$type.'<br/>';
        finfo_close($finfo);
        return in_array($type, $allowed)?$type:false;
    }

    /**
     * 检测是否是wav音频文件
     */
    public static function checkFileIsWav( $audioPath )
    {
        $audioFormat=self::checkFileIsAudio($audioPath);
        if('audio/wav'!=$audioFormat&&'audio/x-wav'!=$audioFormat){
            return false;
        }
        return true;
    }
}